/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
#include "end_correct_stoch.h"
#include "main.h"
#include <assert.h>

/**************************************************************************
*
* ROUTINE
*               EndCorrectStoch
*
* FUNCTION
*               End correct the convolution sum
*
* SYNOPSIS
*               EndCorrectStoch(ExcVal, LPImpResp, LenTruncH, Conv)
*
*   formal
*
*                       data    I/O
*       name            type    type    function
*       -------------------------------------------------------------------
*       ExcVal          fxpt_16  i      Excitation value
*       LPImpResp       fxpt_16  i      LPC impulse response
*       LenTruncH       int      i      Length to truncate impulse response
*       Conv            fxpt_16  o      Convolution sum
*
***************************************************************************
*
*          End correct the convolution sum on subsequent code words:
*          (Do two end corrections for a shift by 2 code book)
*
*          y     =  0
*           0, 0
*          y     =  y        + ex * h   where i = 1, ..., L points
*           i, m     i-1, m-1   -m   i  and   m = 1, ..., cbsize-1 code words
*
*          NOTE:  The data movements in loops "do 59 ..." and "do 69 ..."
*                 are performed many times and can be quite time consuming.
*                 Therefore, special precautions should be taken when
*                 implementing this.  Some implementation suggestions:
*                 1.  Circular buffers with pointers to eliminate data moves.
*                 2.  Fast "block move" operation as offered on some DSPs.
*
*
***************************************************************************/

void EndCorrectStoch(
  fxpt_16       ExcVal,                         /* -1, 0, or +1 */
  fxpt_16       LPImpResp[],                    /* 2.13 format */
  fxpt_16       Conv[])                         /* 15.0 format */
{
  fxpt_16 *Conv_p;
  fxpt_16 *LPImpResp_p;
  int i;

    /* Ternary stochastic code book -- ExcVal is (-1, 0, +1) */
  if( ExcVal==1 )
  {
  Conv[-1] = (LPImpResp[0]+(1 << 12))>>13;
    Conv_p = Conv;
    LPImpResp_p = &LPImpResp[1];
	for( i= LEN_TRUNC_H-1; i>0; --i,++Conv_p,++LPImpResp_p )
      *Conv_p += (*LPImpResp_p + (1 << 12))>>13;
  }
  else if( ExcVal==-1 )
  {
  Conv[-1] = (-LPImpResp[0]+(1 << 12))>>13;
    Conv_p = Conv;
    LPImpResp_p = &LPImpResp[1];
	for( i= LEN_TRUNC_H-1; i>0; --i,++Conv_p,++LPImpResp_p )
      *Conv_p -= (*LPImpResp_p + (1 << 12))>>13;
  }
  else
  {
	Conv[-1] = 0;
  }
}

